package cn.wenhe9.hefengweather.logic

import android.widget.Toast
import androidx.lifecycle.LiveData
import androidx.lifecycle.liveData
import cn.wenhe9.hefengweather.HeFengWeatherApplication
import cn.wenhe9.hefengweather.logic.dao.PlaceDao
import cn.wenhe9.hefengweather.logic.model.Location
import cn.wenhe9.hefengweather.logic.model.Place
import cn.wenhe9.hefengweather.logic.model.Weather
import cn.wenhe9.hefengweather.logic.network.HeFengWeatherNetWork
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlin.Exception
import kotlin.coroutines.CoroutineContext

/**
 *@author DuJinliang
 *2021/10/1
 */
object Repository {
    fun searchPlace(location : String) = fire(Dispatchers.IO){
        val placeResponse = HeFengWeatherNetWork.searchPlaces(location)

        if (placeResponse.code == "200"){
            val places = placeResponse.location
            Result.success(places)
        }else{
            Result.failure(RuntimeException("response status is ${placeResponse.code}"))
        }
    }


    fun refreshWeather(locationId : String) = fire(Dispatchers.IO){
        coroutineScope {
            val deferredRealtime = async {
                HeFengWeatherNetWork.getRealtimeWeather(locationId)
            }
            val deferredDaily = async {
                HeFengWeatherNetWork.getDailyWeather(locationId)
            }
            val deferredLifeIndex = async {
               HeFengWeatherNetWork.getLifeIndex(locationId)
            }

            val realtimeResponse = deferredRealtime.await()
            val dailyResponse = deferredDaily.await()
            val lifeIndexResponse = deferredLifeIndex.await()

            if (realtimeResponse.code == "200" && dailyResponse.code == "200" && lifeIndexResponse.code == "200"){

                val weather = Weather(realtimeResponse.now, dailyResponse.daily, lifeIndexResponse.daily)

                Result.success(weather)
            }else{
                Result.failure(RuntimeException("realtimeResponse status is ${realtimeResponse.code}," + "dailyResponse status is ${dailyResponse.code}" + "lifeIndexResponse status is ${lifeIndexResponse.code}"))
            }
        }
    }

    fun savePlace(place : Location) = PlaceDao.savePlace(place)

    fun getSavedPlace() = PlaceDao.getSavedPlace()

    fun isPlaceSaved() = PlaceDao.isPlaceSaved()

    private fun <T> fire(context : CoroutineContext, block : suspend () -> Result<T>) = liveData<Result<T>>(context){
        val result =  try {
            block()
        }catch (e : Exception){
            Result.failure<T>(e)
        }
        emit(result)
    }
}